package com.ssy.lingxi.member.merchant.controller;

import com.ssy.lingxi.common.constant.member.MemberLevelTypeEnum;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.constant.MemberRelationTypeEnum;
import com.ssy.lingxi.member.merchant.config.ServiceConfig;
import com.ssy.lingxi.member.merchant.entity.*;
import com.ssy.lingxi.member.merchant.model.bo.AgentAreaBO;
import com.ssy.lingxi.member.merchant.model.constant.MemberChannelTypeEnum;
import com.ssy.lingxi.member.merchant.model.constant.MemberStringEnum;
import com.ssy.lingxi.member.merchant.model.constant.MemberUserAuthTypeEnum;
import com.ssy.lingxi.member.merchant.model.constant.MemberValidateStatusEnum;
import com.ssy.lingxi.member.merchant.repository.*;
import com.ssy.lingxi.member.merchant.service.base.IBaseMemberInnerService;
import com.ssy.lingxi.member.merchant.service.feign.IPayFeignService;
import com.ssy.lingxi.member.merchant.service.feign.IWorkflowFeignService;
import com.ssy.lingxi.member.merchant.service.paas.IBasePaasService;
import com.ssy.lingxi.member.merchant.utils.NumberUtil;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 万宁
 * @version 2.0.0
 * @date 2020-08-31
 */
@RestController
@RequestMapping("/member/init")
public class InitController {
    @Resource
    private MemberRepository memberRepository;

    @Resource
    private RoleRepository roleRepository;

    @Resource
    private MemberRelationRepository relationRepository;

    @Resource
    private IBaseMemberInnerService memberInnerService;

    @Resource
    private MemberRoleRepository memberRoleRepository;

    @Resource
    private BaseRightConfigRepository baseRightConfigRepository;

    @Resource
    private BaseLevelConfigRepository baseLevelConfigRepository;

    @Resource
    private MemberLevelRuleConfigRepository memberLevelRuleConfigRepository;

    @Resource
    private IWorkflowFeignService workflowFeignService;

    @Resource
    private IBasePaasService basePaasService;

    @Resource
    private ChannelTypeRepository channelTypeRepository;

    @Resource
    private IPayFeignService payFeignService;

    @Resource
    private MemberLevelConfigRepository memberLevelConfigRepository;

    @Resource
    private MemberRelationRepository memberRelationRepository;

    @Resource
    private MenuRepository menuRepository;

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Transactional
    @RequestMapping("/menu")
    public String updateMenuParentIds() {
        List<MenuDO> menuDOList = menuRepository.findAll();

        for (MenuDO menuDO : menuDOList) {
            if(menuDO.getParentId().equals(0L)) {
                continue;
            }

            if(NumberUtil.isNullOrZero(menuDO.getPaasId())) {
                return "passId null or zero";
            }

            //查找上级菜单
            MenuDO upperMenu = menuDOList.stream().filter(m -> m.getPaasId().equals(menuDO.getParentId())).findFirst().orElse(null);
            if(upperMenu == null) {
                return "upper is null => " + menuDO.getId();
            }

            menuDO.setParentId(upperMenu.getId());
        }

        menuRepository.saveAll(menuDOList);
        return "ok";
    }

    @RequestMapping("/level")
    public String updateMemberLevelConfig() {
        List<BaseLevelConfigDO> baseLevelConfigs = baseLevelConfigRepository.findAll();

        if(CollectionUtils.isEmpty(baseLevelConfigs)) {
            return "empty";
        }

        //找到平台会员
        MemberRelationDO memberRelation = memberRelationRepository.findFirstByRelType(MemberRelationTypeEnum.PLATFORM.getCode());
        if(memberRelation == null) {
            return "null";
        }

        List<MemberLevelConfigDO> memberLevelConfigs = memberLevelConfigRepository.findAll();
        if(CollectionUtils.isEmpty(memberLevelConfigs)) {
            return "level empty";
        }

        List<RoleDO> roleList = roleRepository.findAll();

        Long platformMemberId = memberRelation.getMemberId();
        Long platformRoleId = memberRelation.getRoleId();



        boolean needUpdate = true;
        for (MemberLevelConfigDO memberLevelConfig : memberLevelConfigs) {
            if(StringUtils.hasLength(memberLevelConfig.getLevelTag())) {
                needUpdate = false;
                continue;
            }

            boolean isPlatform = memberLevelConfig.getMemberId().equals(platformMemberId) && memberLevelConfig.getRoleId().equals(platformRoleId);

            if(NumberUtil.isNullOrZero(memberLevelConfig.getLevel())) {
                return "level is null";
            }

            if(NumberUtil.isNullOrZero(memberLevelConfig.getSubRoleId())) {
                return "role is null";
            }

            RoleDO role = roleList.stream().filter(r -> r.getId().equals(memberLevelConfig.getSubRoleId())).findFirst().orElse(null);
            if(role == null) {
                return "role is null";
            }


            Integer levelType = isPlatform ? MemberLevelTypeEnum.PLATFORM.getCode() : MemberLevelTypeEnum.getCodeByMemberType(role.getMemberType().getTypeEnum());

            memberLevelConfig.setLevelType(levelType);
        }

        if(needUpdate) {
            memberLevelConfigRepository.saveAll(memberLevelConfigs);
        }

        String sql = "update ms_mc_member_level_config \n" +
                "set level_tag = bc.level_tag , score_tag = bc.score_tag , remark = bc.remark \n" +
                "from ms_mc_base_level_config bc \n" +
                "where base_level_config_id = bc.id;";
        jdbcTemplate.execute(sql);

        sql = "update ms_mc_member_right_config \n" +
                "set acquire_way = bc.acquire_way_enum , param_way = bc.param_way_enum , right_type = bc.right_type_enum \n" +
                "from ms_mc_base_right_config bc \n" +
                "where base_right_config_id = bc.id and ms_mc_member_right_config.acquire_way is null;";
        jdbcTemplate.execute(sql);

        return "ok";
    }

    /**
     * 重新生成所有会员资金账户
     * @return 操作结果
     */
    @RequestMapping("/accounts")
    public Wrapper<Void> syncAssetAcounts() {
        List<MemberRelationDO> relationDOList = relationRepository.findAll();
        for (MemberRelationDO relationDO : relationDOList) {
            if(!relationDO.getVerified().equals(MemberValidateStatusEnum.VERIFY_PASSED.getCode())) {
                continue;
            }
            payFeignService.notifyMemberAssetAccount(relationDO);
        }

        return Wrapper.success();
    }

    /**
     * 重新构建会员及超管用户权限
     * @param memberId 会员Id
     * @return 操作结果
     */
    @RequestMapping("/auth/rebuild/member")
    public Wrapper<Void> rebuildMemberAuth(Long memberId) {
        MemberDO memberDO = memberRepository.findById(memberId).orElse(null);
        if(memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        return basePaasService.rebuildMemberAuth(memberDO);
    }

    /**
     * 根据角色，重新构建权限
     * @param roleId 角色Id
     * @return 操作结果
     */
    @RequestMapping("/auth/rebuild/role")
    public Wrapper<Void> syncRoleAuth(Long roleId) {
        RoleDO roleDO = roleRepository.findById(roleId).orElse(null);
        if(roleDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        return basePaasService.rebuildAuth(roleDO);
    }

    /**
     * 根据会员，重新构建权限
     * @param memberId 会员Id
     * @return 操作结果
     */
    @RequestMapping("/auth/rebuild/role/by/member")
    public Wrapper<Void> syncMemberAuth(Long memberId) {
        MemberDO member = memberRepository.findById(memberId).orElse(null);
        if(member == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        List<RoleDO> roleList = new ArrayList<>(member.getRoles());
        for (RoleDO roleDO : roleList) {
            Wrapper<Void> result = basePaasService.rebuildAuth(roleDO);
            if(result.getCode() != ResponseCode.SUCCESS.getCode()) {
                return result;
            }
        }

        return Wrapper.success();
    }

    @RequestMapping("/relation/rebuild")
    public String buildRelation() {
        List<MemberRelationDO> relationDOList = relationRepository.findAll();
        ChannelTypeDO channelTypeDO = channelTypeRepository.findAll().stream().filter(c -> c.getChannelTypeEnum().equals(MemberChannelTypeEnum.ECOMMERCE.getCode())).findFirst().orElse(null);
        if(channelTypeDO == null) {
            return "类型不存在";
        }

        for (MemberRelationDO relationDO : relationDOList) {
            if(relationDO.getRelType().equals(MemberRelationTypeEnum.PLATFORM.getCode())) {
                if(!relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.PLATFORM.getCode())) {
                    return "level error";
                }
                relationDO.setChannel(null);
            } else {
                if(!relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.getCodeByMemberType(relationDO.getSubRole().getMemberType().getTypeEnum()))) {
                    return "level error 2";
                }

                MemberChannelDO channelDO = new MemberChannelDO();
                channelDO.setChannelType(channelTypeDO);
                channelDO.setRemark("");
                channelDO.setChannelLevelTag(MemberStringEnum.MEMBER_CHANNEL_DEFAULT_LEVEL_TAG.getName());
                channelDO.setLevel(ServiceConfig.MEMBER_CHANNEL_DEFAULT_LEVEL);
                channelDO.setAgentArea(new AgentAreaBO());
                relationDO.setChannel(channelDO);
            }
        }

        relationRepository.saveAll(relationDOList);
        return "ok";
    }

    /**
     * 同步所有用户角色到工作流
     * @return 操作结果
     */
    @RequestMapping("/sync/member/role/to/workflow")
    public String syncAllMemberRoleToWorkflowService() {
        List<MemberRoleDO> memberRoleDOList = memberRoleRepository.findAll();
        for (MemberRoleDO memberRoleDO : memberRoleDOList) {
            if(memberRoleDO.getTypeEnum().equals(MemberUserAuthTypeEnum.ADMIN.getCode()) || memberRoleDO.getMember().getName().equals(MemberStringEnum.PLATFORM_SUPER_ADMIN_MEMBER_NAME.getName())) {
                continue;
            }

            workflowFeignService.upsertMemberRoleToProcessAsync(memberRoleDO.getMember().getId(), memberRoleDO.getId(), memberRoleDO.getRoleName(), memberRoleDO.getAuth());
        }

        return "ok";
    }

    /**
     * 删除会员
     * @param memberId 会员Id
     * @param roleId 角色Id
     * @return 删除结果
     */
    @RequestMapping("/delete")
    public String delete(Long memberId, Long roleId) {
        MemberDO memberDO = memberRepository.findById(memberId).orElse(null);
        RoleDO roleDO = roleRepository.findById(roleId).orElse(null);

        if(memberDO == null) {
            return "会员为空";
        }

        if(roleDO == null) {
            return "角色为空";
        }

        memberInnerService.deleteMemberCompletely(memberDO, roleDO);
        return "OK";
    }

    /**
     * 删除会员关系
     * @return 删除结果
     */
    @RequestMapping("/relation/delete")
    public String delete(Long relationId) {
        MemberRelationDO relationDO = relationRepository.findById(relationId).orElse(null);
        if(relationDO == null) {
            return "null";
        }

        relationRepository.delete(relationDO);

        return "OK";
    }


}


